home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
haeberli
/
libgutil
/
sptexture.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
13KB
|
641 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* sptexture -
* Stapuft comatible texture mapping support
*
* Paul Haeberli - 1989
*/
#include "stdio.h"
#include "gl.h"
#include "stdio.h"
#include "math.h"
#include "vect.h"
#include "sgiobj.h"
#include "lum.h"
#include "texture.h"
#include "gfxmach.h"
static faket2f();
static realtextureread();
static faketextureread();
static faketmcolor();
static faketmc3f();
#define MAXTEXTURES 20
/*
* generic texture stuff
*
*/
vect texavg[MAXTEXTURES+1];
static int bwmode;
static int fasttmp = -1;
fasttm()
{
if(fasttmp>=0)
return fasttmp;
if(getgdesc(GD_TEXTURE))
fasttmp = 1;
else
fasttmp = 0;
return fasttmp;
}
setbwmode(b)
{
bwmode = b;
}
llum(c)
long c;
{
int r, g, b, a, l;
r = (c>>0 )&0xff;
g = (c>>8 )&0xff;
b = (c>>16)&0xff;
a = (c>>24)&0xff;
l = ILUM(r,g,b);
c = (a<<24)+(l*0x10101);
}
vlum(c)
vect *c;
{
float l;
l = LUM(c->x,c->y,c->z);
c->x = l;
c->y = l;
c->z = l;
}
/*
* general texture mapping functions
*
*
*/
void myt2f(t)
float *t;
{
if(fasttm())
t2f(t);
else
faket2f(t);
}
textureread(name,texno)
char *name;
int texno;
{
if(fasttm())
realtextureread(name,texno);
else
faketextureread(name,texno);
}
settexture(n)
int n;
{
if(fasttm())
realsettexture(n);
else
fakesettexture(n);
}
tmcolor(c)
long c;
{
if(fasttm())
realtmcolor(c);
else
faketmcolor(c);
}
tmc3f(c)
vect *c;
{
if(fasttm())
c3f((float*)c);
else
faketmc3f(c);
}
/*
* real texture mapping functions
*
*
*/
static int firsted;
static int texon;
static realtextureread(name,texno)
char *name;
int texno;
{
unsigned long *imagedata;
int i, xsize, ysize;
static float texps[] = {TX_MINFILTER,TX_MIPMAP_BILINEAR,TX_MAGFILTER,TX_BILINEAR,TX_NULL};
static float texps256[] = {TX_MAGFILTER,TX_BILINEAR,TX_MINFILTER,TX_POINT,TX_WRAP,TX_CLAMP,TX_NULL};
static float tevps[] = {TV_MODULATE,TV_NULL};
char cmd[256];
float sx, sy;
if(texno> MAXTEXTURES) {
fprintf(stderr,"textureread: texno %d exceeds maxtextures %d\n",texno);
exit(1);
}
sizeofimage(name,&xsize,&ysize);
imagedata = (unsigned long *)longimagedata(name);
lrectavg(imagedata,xsize,ysize,&texavg[texno]);
if(xsize == 256 && ysize == 256)
texdef2d(texno,4,xsize,ysize,imagedata,7,texps256);
else
texdef2d(texno,4,xsize,ysize,imagedata,5,texps);
if(!firsted) {
tevdef(1,0,tevps);
firsted = 1;
settexture(1);
}
}
realsettexture(n)
int n;
{
if(n==0) {
texbind(0,0);
tevbind(0,0);
texon = 0;
} else {
texbind(0,n);
if(texon == 0) {
tevbind(0,1);
texon = 1;
}
}
}
realtmcolor(c)
long c;
{
if(bwmode)
c = llum(c);
cpack(c);
}
/*
* fake texture mapping functions
*
*
*/
static TEXTURE *tm[MAXTEXTURES+1];
static int curtex;
static float curtmr = 1.0;
static float curtmg = 1.0;
static float curtmb = 1.0;
static faketextureread(name,texno)
char *name;
int texno;
{
if(texno> MAXTEXTURES) {
fprintf(stderr,"textureread: texno %d exceeds maxtextures %d\n",texno);
exit(1);
}
tm[texno] = tmopen(name);
if(tm[texno] == 0) {
fprintf(stderr,"textureread: can't open input file %s\n",name);
exit(1);
}
tmavg(tm[texno],&texavg[texno]);
curtex = texno;
}
fakesettexture(n)
int n;
{
curtex = n;
}
#define ALMOSTONE (0.9999)
static faket2f(t)
float t[2];
{
vect c;
fakettoc(t,&c);
c3f((float*)&c);
}
fakettoc(t,c)
float t[2];
vect *c;
{
vect p;
p.x = ALMOSTONE*t[0];
p.y = ALMOSTONE*t[1];
p.z = 0.0;
tmsample(tm[curtex],&p,c);
c->x *= curtmr;
c->y *= curtmg;
c->z *= curtmb;
c->w = 1.0;
if(bwmode)
vlum(c);
}
static faketmcolor(c)
long c;
{
curtmr = ((c>>0)&0xff)/255.0;
curtmg = ((c>>8)&0xff)/255.0;
curtmb = ((c>>16)&0xff)/255.0;
cpack(c&0xffffff);
}
static faketmc3f(c)
vect *c;
{
curtmr = c->x;
curtmg = c->y;
curtmb = c->z;
c3f((float*)c);
}
textureaverage(texno,avg)
int texno;
vect *avg;
{
*avg = texavg[texno];
}
/*
* environment mapping stuff
*
*/
static int localenv;
envmaplocal(v)
int v;
{
localenv = v;
if(v)
fprintf(stderr,"shade: local viewer\n");
else
fprintf(stderr,"shade: infinite viewer\n");
}
xformnorm(matrix,v,tv)
float matrix[4][4];
vect *v, *tv;
{
tv->x = v->x*matrix[0][0] + v->y*matrix[1][0] + v->z*matrix[2][0];
tv->y = v->x*matrix[0][1] + v->y*matrix[1][1] + v->z*matrix[2][1];
tv->z = v->x*matrix[0][2] + v->y*matrix[1][2] + v->z*matrix[2][2];
}
xformvert(matrix,v,tv)
float matrix[4][4];
vect *v, *tv;
{
tv->x = v->x*matrix[0][0] + v->y*matrix[1][0] + v->z*matrix[2][0]
+ matrix[3][0];
tv->y = v->x*matrix[0][1] + v->y*matrix[1][1] + v->z*matrix[2][1]
+ matrix[3][1];
tv->z = v->x*matrix[0][2] + v->y*matrix[1][2] + v->z*matrix[2][2]
+ matrix[3][2];
}
xformvert4(matrix,v,tv)
float matrix[4][4];
vect *v, *tv;
{
tv->x = v->x*matrix[0][0] + v->y*matrix[1][0] + v->z*matrix[2][0]
+ matrix[3][0];
tv->y = v->x*matrix[0][1] + v->y*matrix[1][1] + v->z*matrix[2][1]
+ matrix[3][1];
tv->z = v->x*matrix[0][2] + v->y*matrix[1][2] + v->z*matrix[2][2]
+ matrix[3][2];
tv->w = v->x*matrix[0][3] + v->y*matrix[1][3] + v->z*matrix[2][3]
+ matrix[3][3];
}
static float vmat[4][4];
static float nmat[4][4];
static float psmat[4][4];
normmat(imat,normalmat)
float imat[4][4];
float normalmat[4][4];
{
vect n, tn;
float len;
int x, y;
n.x = 1.0;
n.y = 0.0;
n.z = 0.0;
xformnorm(imat,&n,&tn);
len = vlength(&tn);
for(y=0; y<4; y++)
for(x=0; x<4; x++)
normalmat[y][x] = imat[y][x]/len;
}
tenvmat(mat)
float *mat;
{
copymat(mat,vmat);
normmat(mat,nmat);
}
#define DENOM (2.15)
tenv(n,p,t)
vect *n, *p, *t;
{
vect eye, tn, tp;
vect ref, ahead, half, c;
float mag, dot;
if(!localenv) {
tn.x = n->x*nmat[0][0] + n->y*nmat[1][0] + n->z*nmat[2][0];
tn.y = n->x*nmat[0][1] + n->y*nmat[1][1] + n->z*nmat[2][1];
t->x = 0.5+tn.x/DENOM;
t->y = 0.5+tn.y/DENOM;
} else {
tn.x = n->x*nmat[0][0] + n->y*nmat[1][0] + n->z*nmat[2][0];
tn.y = n->x*nmat[0][1] + n->y*nmat[1][1] + n->z*nmat[2][1];
tn.z = n->x*nmat[0][2] + n->y*nmat[1][2] + n->z*nmat[2][2];
eye.x = p->x*vmat[0][0] + p->y*vmat[1][0] + p->z*vmat[2][0]
+ vmat[3][0];
eye.y = p->x*vmat[0][1] + p->y*vmat[1][1] + p->z*vmat[2][1]
+ vmat[3][1];
eye.z = p->x*vmat[0][2] + p->y*vmat[1][2] + p->z*vmat[2][2]
+ vmat[3][2];
/* vnormal */
mag = sqrt(eye.x*eye.x + eye.y*eye.y + eye.z*eye.z);
/* vreflect */
dot = -2.0*(tn.x*eye.x+tn.y*eye.y+tn.z*eye.z);
ref.x = dot*tn.x+eye.x;
ref.y = dot*tn.y+eye.y;
ref.z = dot*tn.z+eye.z+mag;
/* vhalf */
mag = DENOM*sqrt(ref.x*ref.x + ref.y*ref.y + ref.z*ref.z);
if(mag<0.0001) {
t->x = 0.5;
t->y = 0.5;
} else {
t->x = 0.5+(ref.x/mag);
t->y = 0.5+(ref.y/mag);
}
}
}
#define BYTEOFF(v) (sizeof(long)*(v))
static float *envprojmat;
static envtrifunc(p0,p1,p2)
long *p0, *p1, *p2;
{
vect t, c0, c1, c2;
tenv(p0+OFFSET_NORMAL,p0+OFFSET_POINT,&t);
fakettoc(&t,&c0);
tenv(p1+OFFSET_NORMAL,p1+OFFSET_POINT,&t);
fakettoc(&t,&c1);
tenv(p2+OFFSET_NORMAL,p2+OFFSET_POINT,&t);
fakettoc(&t,&c2);
bgnpolygon();
c3f((float*)&c0);
v3f((float*)(p0+OFFSET_POINT));
c3f((float*)&c1);
v3f((float*)(p1+OFFSET_POINT));
c3f((float*)&c2);
v3f((float*)(p2+OFFSET_POINT));
endpolygon();
}
drawenvobj(obj,mat)
sgiobj *obj;
float mat[4][4];
{
if(fasttm()) {
texgen(TX_S, TG_SPHEREMAP, 0);
texgen(TX_T, TG_SPHEREMAP, 0);
texgen(TX_S, TG_ON, NULL);
texgen(TX_T, TG_ON, NULL);
drawsgiobj(obj,DRAW_POINTS|DRAW_NORMALS);
texgen(TX_S, TG_OFF, NULL);
texgen(TX_T, TG_OFF, NULL);
} else {
tenvmat(mat);
applytotris(obj,envtrifunc);
}
}
normtoc(n,c)
vect *n, *c;
{
vect tn;
xformnorm(nmat,n,&tn);
c->x = (tn.x+1.0)/2.0;
c->y = (tn.y+1.0)/2.0;
c->z = (tn.z+1.0)/2.0;
}
static trinorm(verts)
float *verts[3];
{
vect n0, n1, n2;
normtoc(verts[0]+OFFSET_NORMAL,&n0);
normtoc(verts[1]+OFFSET_NORMAL,&n1);
normtoc(verts[2]+OFFSET_NORMAL,&n2);
bgnpolygon();
c3f((float*)&n0);
v3f(verts[0]+OFFSET_POINT);
c3f((float*)&n1);
v3f(verts[1]+OFFSET_POINT);
c3f((float*)&n2);
v3f(verts[2]+OFFSET_POINT);
endpolygon();
}
drawnormobj(obj,mat)
sgiobj *obj;
float mat[4][4];
{
float *p;
int npolys;
vect n0, n1, n2, n3;
normmat(mat,nmat);
p = (float *)obj->data;
if(obj->objtype == OBJ_QUADLIST) {
npolys = (obj->nlongs/PNTLONGS)/4;
while(npolys--) {
normtoc(p+(0*PNTLONGS)+OFFSET_NORMAL,&n0);
normtoc(p+(1*PNTLONGS)+OFFSET_NORMAL,&n1);
normtoc(p+(2*PNTLONGS)+OFFSET_NORMAL,&n2);
normtoc(p+(3*PNTLONGS)+OFFSET_NORMAL,&n3);
bgntmesh();
c3f((float*)&n0);
v3f(p+(0*PNTLONGS)+OFFSET_POINT);
c3f((float*)&n1);
v3f(p+(1*PNTLONGS)+OFFSET_POINT);
c3f((float*)&n3);
v3f(p+(3*PNTLONGS)+OFFSET_POINT);
c3f((float*)&n2);
v3f(p+(2*PNTLONGS)+OFFSET_POINT);
endtmesh();
p += 4*PNTLONGS;
}
} else if(obj->objtype == OBJ_TRILIST) {
npolys = (obj->nlongs/PNTLONGS)/3;
while(npolys--) {
normtoc(p+(0*PNTLONGS)+OFFSET_NORMAL,&n0);
normtoc(p+(1*PNTLONGS)+OFFSET_NORMAL,&n1);
normtoc(p+(2*PNTLONGS)+OFFSET_NORMAL,&n2);
bgntmesh();
c3f((float*)&n0);
v3f(p+(0*PNTLONGS)+OFFSET_POINT);
c3f((float*)&n1);
v3f(p+(1*PNTLONGS)+OFFSET_POINT);
c3f((float*)&n2);
v3f(p+(2*PNTLONGS)+OFFSET_POINT);
endtmesh();
p += 3*PNTLONGS;
}
} else if(obj->objtype == OBJ_TRIMESH) { /* could go faster */
applytomeshtris(obj,trinorm);
}
}
drawprojection(obj,mat)
sgiobj *obj;
float mat[4][4];
{
float *p;
int npolys;
vect n0, n1, n2, n3;
p = (float *)obj->data;
tenvmat(mat);
pushmatrix();
scale(-3.0,3.0,0.0);
translate(-0.5,-0.5,0.0);
cpack(0xffffff);
drawcirc(0.5,0.5,0.5);
if(obj->objtype == OBJ_QUADLIST) {
npolys = (obj->nlongs/PNTLONGS)/4;
while(npolys--) {
tenv(p+(0*PNTLONGS)+OFFSET_NORMAL,p+(0*PNTLONGS)+OFFSET_POINT,&n0);
tenv(p+(1*PNTLONGS)+OFFSET_NORMAL,p+(1*PNTLONGS)+OFFSET_POINT,&n1);
tenv(p+(2*PNTLONGS)+OFFSET_NORMAL,p+(2*PNTLONGS)+OFFSET_POINT,&n2);
tenv(p+(3*PNTLONGS)+OFFSET_NORMAL,p+(3*PNTLONGS)+OFFSET_POINT,&n3);
bgnclosedline();
v2f((float*)&n0);
v2f((float*)&n1);
v2f((float*)&n3);
endclosedline();
bgnclosedline();
v2f((float*)&n1);
v2f((float*)&n3);
v2f((float*)&n2);
endclosedline();
p += 4*PNTLONGS;
}
} else if(obj->objtype == OBJ_TRILIST) {
npolys = (obj->nlongs/PNTLONGS)/3;
while(npolys--) {
tenv(p+(0*PNTLONGS)+OFFSET_NORMAL,p+(0*PNTLONGS)+OFFSET_POINT,&n0);
tenv(p+(1*PNTLONGS)+OFFSET_NORMAL,p+(1*PNTLONGS)+OFFSET_POINT,&n1);
tenv(p+(2*PNTLONGS)+OFFSET_NORMAL,p+(2*PNTLONGS)+OFFSET_POINT,&n2);
bgnclosedline();
v2f((float*)&n0);
v2f((float*)&n1);
v2f((float*)&n3);
endclosedline();
p += 3*PNTLONGS;
}
}
popmatrix();
}
/*
* background drawing stuff follows
*
*/
static int backixsize, backiysize;
static unsigned long *backimgdat;
drawback(name)
char *name;
{
if(!backimgdat) {
sizeofimage(name,&backixsize,&backiysize);
backimgdat = (unsigned long *)longimagedata(name);
}
ortho2(0.0,1.0,0.0,1.0);
pushmatrix();
myidentity();
drawquadlimage(backimgdat,backixsize,backiysize);
popmatrix();
restorewindow();
}
lrectavg(data,xsize,ysize,avg)
unsigned long *data;
int xsize, ysize;
vect *avg;
{
int n;
unsigned long rav, gav, bav, aav;
n = xsize*ysize;
if(n>(256*256*256)) {
fprintf(stderr,"lrectavg: size too big\n");
exit(1);
}
rav = gav = bav = aav = 0;
while(n--) {
rav += ((*data)>>0)&0xff;
gav += ((*data)>>8)&0xff;
bav += ((*data)>>16)&0xff;
aav += ((*data)>>24)&0xff;
data++;
}
n = xsize*ysize;
avg->x = ((float)rav/n)/255.0;
avg->y = ((float)gav/n)/255.0;
avg->z = ((float)bav/n)/255.0;
avg->w = ((float)aav/n)/255.0;
printf("lrectavg ");
vprint(avg);
}